package com.rtsapp.server.common;

import com.rtsapp.server.logger.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;

/*
* 注册事件监听
* 发布事件
*
* 目前运行都是同步的, 后期有需要再考虑
*/
public class EventManager {

    private static final Logger LOGGER =com.rtsapp.server.logger.LoggerFactory.getLogger( EventManager.class );

    private ConcurrentMap<Integer, List<EventListener>> eventListeners = new ConcurrentHashMap<>();


    private static EventManager instance = new EventManager();


    public static EventManager getInstance( ) {
        return instance;
    }


    /**
     * 注册监听单个事件id
     * 同一个事件，一个listener只会被注册一次, listener不能为null
     * 该方法是线程安全的
     * @param eventId
     * @param listener
     */
    public void registerListener(int eventId, EventListener listener) {

        if( listener == null ){
            return;
        }

        List<EventListener> listeners = getOrCreateListenersByEventId(eventId);

        //该处的
        if (!listeners.contains(listener)) {
            synchronized ( listeners ){
                if ( !listeners.contains(listener) ){
                    listeners.add(listener);
                }
            }
        }

    }

    /**
     * 注册监听一组事件
     * 同一个事件，一个listener只会被注册一次
     *
     * @param eventIds
     * @param listener
     */
    public void registerListener(int[] eventIds, EventListener listener) {
        if( listener == null ){
            return;
        }

        for (int eventId : eventIds) {
            registerListener(eventId, listener);
        }
    }

    /**
     * 移除对单个事件的监听
     * 该方法线程安全
     * @param eventId
     * @param listener
     */
    public void removeListener(int eventId, EventListener listener) {
        if( listener == null ){
            return;
        }

        List<EventListener> listeners = getOrCreateListenersByEventId(eventId);

        //该处的
        if ( listeners.contains(listener)) {
            synchronized ( listeners ){
                if ( listeners.contains(listener) ){
                    listeners.remove(listener);
                }
            }
        }
    }


    /**
     * 移除对一组事件的监听
     *
     * @param eventIds
     * @param listener
     */
    public void removeListener(int[] eventIds, EventListener listener) {
        if( listener == null ){
            return;
        }

        for( int id : eventIds ){
            removeListener( id, listener );
        }
    }

    /**
     * 移除listener的所有监听
     */
    public void removeListener(EventListener listener) {
        if( listener == null ){
            return;
        }

        for( Iterator<Integer> it =  eventListeners.keySet().iterator(); it.hasNext(); ){
            removeListener( it.next(), listener );
        }

    }


    public void sendEvent( Event event ){
        List<EventListener> listeners = getOrCreateListenersByEventId( event.getEventId() );
        for(  EventListener listener : listeners ){
            try {
                listener.onEvent(event);
            }catch( Throwable ex ){
                LOGGER.error( "sendEvent error: event={id="+event.getEventId()+","+event , ex );
            }
        }
    }




    private List<EventListener> getOrCreateListenersByEventId(int eventId) {
        List<EventListener> listeners = eventListeners.get(eventId);
        if (listeners == null) {
            listeners = new CopyOnWriteArrayList<>();
            List<EventListener> oldListeners = eventListeners.putIfAbsent(eventId, listeners);
            if (oldListeners != null) {
                listeners = oldListeners;
            }
        }
        return listeners;
    }


}
